var commMap = new HashMap();//公共信息
var instalOrderMap = new HashMap();//分期
var num = 0;
var iframeName = "body";
var undoneNewBalance = new BigDecimal("0");//未出账单已入账金额
var checkCardTimes = 0;
var imgCount = 0;
var loginrsp = "";

var v6_pingan_credit_java_funcs = {
    openHomePage : function(){
        //打开页面判断代理是否异常
        var html = luaFuncs.get("https://creditcard.pingan.com.cn/financing/login.screen");
        context.put("index_html",html);
    },
    //检测代理是否可用
    checkProxyAvailable: function(){
        logger.info("任务【{}】，平安信用卡开始检测代理是否可用",context.get(LUA_TASK_TOKEN));
        var html = context.get("index_html");
        var isCorrectFunc = function(html){
            return true;
        }
        //获取异常信息的方法function
        var getErrorMsgFunc = function(html) {
            return "代理ip异常";
        }
        //返回信息
        return assertTrueOrThrowException(html, isCorrectFunc, getErrorMsgFunc)
    },
    checkControlAvailable:function () {
        logger.info("任务【{}】，平安信用卡开始进行控件可用性检测",context.get(LUA_TASK_TOKEN));
        return true;
    },
    checkTargetWebsiteAvailable: function(){
        logger.info("任务【{}】, 平安信用卡网站是否可用方法", context.get(LUA_TASK_KEY));
        return true;
    },
    needRefreshHomePageOrNot : function() {
        return equals(context.get("currentErrorCode"), BALO_99602_50)
    },
    needResetEnvironment:function(){
        return true;
    },
    // 登录过程
    login:function () {

        //输入用户名密码
        inputNameAndPwd();

        //输入图片验证码
        inputSmsAndGetError();

    },
    crawl:function(){

        var dataList = new ArrayList();

        var creditCardAllData = new CreditCardAllData();
        //抓取卡的数量
        crawlCardNum();

        //解析卡号信息
        praseCardSize();

        //抓取基本信息
        crawlBaseInfo();

        //保存基本信息
        saveBasicInfo(creditCardAllData);

        //抓取并且保存已出账单
        crawlAndSaveDoneBills(creditCardAllData);

        //保存未出账单
        crawlAndsaveUndoneBills(creditCardAllData);

        //var data = getDataMes(cardNo);

        dataList.add(creditCardAllData);
        context.put("credit_data", dataList);
    },
    exitLogin:function () {
    },
    releaseResources:function(){}
}


function inputSms () {
    //判断页面是否渲染成功
    show()
    /*var exist = luaFuncs.frame_is_exist_by_id("Tarrow01", "body,wait");
     var count = 0;
     while(!exist){
     exist = luaFuncs.frame_is_exist_by_id("Tarrow01", "body,wait");
     Thread.sleep(2000)
     if(count==11){//重试n次，防止网络延迟
     logger.info("平安银行页面未获取到卡片信息，taskKey:{}", context.get(LUA_TASK_KEY));
     return "没有相关信用卡卡片信息";
     //throw new BankException(BALO_20304_30, "未获取到卡片信息");
     }
     count++;
     }*/
    logger.info("任务【{}】，页面渲染完成",context.get(LUA_TASK_KEY))

    //判断查询密码是否设置
    var isNoSet = luaFuncs.frame_is_exist_by_id("wrapper", "body,menuFrameID");
    //截图
    var imgpath = luaFuncs.get_screen_img();
    //logger.info("查询密码未设置的页面地址是：{}",imgpath+count);
    if(isNoSet){
        return "查询密码未设置"
        //throw new BankException(BALO_22005_10, "查询密码未设置");
    }
    //保存页面
    loginrsp = luaFuncs.find_frame_html();
    storeDataToFile(context, loginrsp, "loginrsp.txt")
    //判断是否添加信用卡信息
    if(loginrsp.contains("添加信用卡")){
        logger.info("您尚未添加信用卡");
        return "没有相关信用卡卡片信息";
        //throw new BankException(BALO_20304_30, "没有相关信用卡卡片信息");
    }

    //判断信用卡是否为新版
    var exist_new = luaFuncs.frame_is_exist_by_id("creditcardIndexLink", "body,header");
    if(exist_new){
        logger.info("平安信用卡为新版:{}, taskKey:{}", exist_new, context.get(LUA_TASK_KEY));
        iframeName = "body,wait";
    }

    //校验是否需要短信验证码，以及登录之后是否有错误
    var check_result = checkSms()
    var checkIsNeedSmsFun = function(check_result){
        return check_result.equals("true") || check_result.equals("false");
    }
    //获取异常信息的方法function
    var checkNeedSmsErrorFun = function(check_result) {
        return check_result;
    }
    //返回信息
    assertTrueOrThrowException(check_result, checkIsNeedSmsFun, checkNeedSmsErrorFun);

    if(check_result.equals("true")){
        //等待用户输入短信验证码
        hide()
        var smsCode = waitSmsCodeBySeconds(context,180);
        show()
        Thread.sleep(300);
        //输入短信验证码
        //set_frame_input_text_by_id("DynamicPassword",smsCode,"body,wait");
        var input_result = luaFuncs.input_sms_frame(smsCode);
        logger.info("任务【{}】，短信验证码输入结果，【{}】",context.get(LUA_TASK_KEY),input_result);
        //click_frame_by_id("submitBtn","body,wait")
        luaFuncs.screen_print();//截图
        Thread.sleep(5000)
        hide();
        //校验短信验证码是否输入有误
        var inputSmsisokFun = function(input_result){
            return input_result.equals("yes") || input_result.equals("return is null");
        }
        //获取异常信息的方法function
        var getInputSmsErrorMsgFunc = function(input_result) {
            return input_result;
        }
        //返回信息
        assertTrueOrThrowException(input_result, inputSmsisokFun, getInputSmsErrorMsgFunc);
        Thread.sleep(5000)
    }

    //判断是否包含壹钱包来进行下一步操作
    if(loginrsp.contains("壹钱包")){
        //判断广告是否存在
        luaFuncs.check_is_id_exit();
        //关闭广告
        luaFuncs.click_class_name_frame();
        //点击信用卡入口
        luaFuncs.click_credit();
    }else{
        //点击我的帐单
        luaFuncs.click_bill();
    }
    //判断是否进入到信用卡账单页面
    var status = luaFuncs.frame_is_exist_by_id("hasBill", "body");
    return "true";
}
/**
 * 获取卡号
 */
function praseCardSize() {
    var bankSetInfo = context.get("bankSetInfo");
    var bankSetMap = JSON.parse(bankSetInfo);
    var accounts =  bankSetMap.get("accounts");
    var accountMap = accounts.get(0);
    var cardSet = accountMap.get("cardSet");
    for (var i = 0; i < 1; i++) {
        num = i+1;
        var card = cardSet.get(i);
        var cardNo = card.get("cardNo");
        context.put("cardNo",cardNo)
    }
    logger.info("平安银行抓取结果完成，taskKey:{}", context.get(LUA_TASK_KEY));
}
/***
 *  抓取卡的数量
 */

function crawlCardNum() {
    var url = "https://creditcard.pingan.com.cn/financing/newccuser/listAccountforCardInfo.do";
    var bankSetInfo = luaFuncs.ajax_frame_post(url, new HashMap(), iframeName);
    storeDataToFile(context, bankSetInfo, "1_bankset_1.txt")
    context.put("bankSetInfo",bankSetInfo);
}
/**
 * 输入短信验证码并且校验是否有错
 */
function inputSmsAndGetError() {

    logger.info("任务【{}】,平安信用卡开始获取并自动打码图片验证码",context.get(LUA_TASK_KEY));
    var loginHtml = getCode(LUA_TASK_KEY);
    //保存
    storeDataToFile(context, loginHtml, "login.txt")
    //提取登录页面错误码
    var error_msg = getLoginErrorMsg(loginHtml)
    logger.info("任务【{}】，登录结果："+error_msg,context.get(LUA_TASK_KEY));
    //判断是否登录成功，true登录成功，false表示图片验证码错误
    //var status = checkLoginStatus(loginHtml);
    var isLoginSucFunc = function(error_msg){
        return error_msg.equals("yes");
    }
    //获取异常信息的方法function
    var getLoginErrorMsgFunc = function(error_msg) {
        return error_msg;
    }
    //返回信息
    assertTrueOrThrowException(error_msg, isLoginSucFunc, getLoginErrorMsgFunc);

    //校验用户名密码是否正确输入的流程
    if(error_msg.equals("yes")){
        logger.info("平安银行等待页面加载，taskKey:{}", context.get(LUA_TASK_KEY));
        Thread.sleep(8000);
        logger.info("平安银行等待页面完成，taskKey:{}", context.get(LUA_TASK_KEY));
        //检查是否有信用卡信息
        var checkcard_status = checkCard(loginHtml);
        var isCheckCardSucFunc = function(checkcard_status){
            return checkcard_status.equals("true");
        }
        //获取异常信息的方法function
        var getCheckCardErrorMsgFunc = function(checkcard_status) {
            return checkcard_status;
        }
        //返回信息
        assertTrueOrThrowException(checkcard_status, isCheckCardSucFunc, getCheckCardErrorMsgFunc);
    }
    logger.info("任务【{}】，登录成功，开始校验是否需要短信验证码",context.get(LUA_TASK_KEY));
    var smsReuslt = inputSms();
    //校验短信验证码的发送输入的流程是否正确
    var smsIsRightInputFunc = function(smsReuslt){
        return smsReuslt.equals("true");
    }
    //获取异常信息的方法function
    var getSmsInputErrorFunc = function(smsReuslt) {
        return smsReuslt;
    }
    //返回信息
    assertTrueOrThrowException(smsReuslt, smsIsRightInputFunc, getSmsInputErrorFunc);
}
/***
 *  输入用户名和密码
 */
function inputNameAndPwd() {
    logger.info("任务【{}】，平安信用卡开始进入到登录过程",context.get(LUA_TASK_KEY));
    logger.info("------------------------------LOGIN START---------------------------------")
    logger.info("任务【{}】，平安信用卡开始获取登录参数",context.get(LUA_TASK_KEY));
    //获取用户名密码
    var userName = getLoginParams(context)[0];
    var pwd = context.get(LUA_TASK_TOKEN);
    var checkUandPResult = StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(pwd) && pwd.length>=6;
    //检测获取到的用户名和密码是否符合规则 用户名密码校验未通过
    var isRightUserNameAndPwdFunc = function(checkUandPResult){
        return checkUandPResult;
    }
    //获取异常信息的方法function
    var getUserTipsErrorMsgFunc = function(checkUandPResult) {
        return "用户名密码校验未通过";
    }
    //返回信息
    assertTrueOrThrowException(checkUandPResult, isRightUserNameAndPwdFunc, getUserTipsErrorMsgFunc);
    logger.info("任务【{}】，平安信用卡用户名密码校验通过",context.get(LUA_TASK_KEY));
    logger.info("任务【{}】，平安信用卡，开始调用lua脚本输入用户名密码",context.get(LUA_TASK_KEY));
    //输入用户名和密码
    var inputMsg = "true";
    var openstatus = luaFuncs.set_frame_input_text(userName,pwd);
    //再次获取密码，防止密码没有输入
    var inputpwd = luaFuncs.get_frame_pwd();
    //密码没有为空的重试次数
    var count = 0;
    for(var i = 0;i<=5;i++){
        //如果取回来的密码为空，则再次输入用户名和密码，并获取密码
        if(inputpwd.equals("fail")){
            count++;
            //输入用户名和密码
            openstatus = luaFuncs.set_frame_input_text(userName,pwd);
            //获取密码
            inputpwd = luaFuncs.get_frame_pwd();
        }else{
            break;
        }
    }
    //如果重试五次密码仍然为空，则说明没有点中小键盘
    if(count>5){
        logger.info("任务【{}】，平安银行键盘未点击",context.get(LUA_TASK_KEY));
        inputMsg = "平安银行键盘未点击";
    }
    //如果页面包含无法显示此页面或者为空，则说明代理ip异常
    if(openstatus.contains("无法显示此页面") || openstatus.isEmpty()){
        logger.info("任务【{}】，平安银行代理ip异常",context.get(LUA_TASK_KEY));
        inputMsg = "代理ip异常"
    }
    //校验用户名密码是否正确输入的流程
    var isInputRightFunc = function(inputMsg){
        return inputMsg.equals("true");
    }
    //获取异常信息的方法function
    var getInputErrorMsgFunc = function(inputMsg) {
        return "用户名密码校验未通过";
    }
    //返回信息
    assertTrueOrThrowException(inputMsg, isInputRightFunc, getInputErrorMsgFunc);
    logger.info("任务【{}】，平安信用卡用户名密码正确输入",context.get(LUA_TASK_KEY));
}
/**
 * 获取数据
 * @param cardNo
 * @returns {CreditCardAllData}
 */
function getDataMes(cardNo) {

    //存储对象
    var data = new CreditCardAllData();
    //账单列表
    data.setBills(new ArrayList());
    //存款信息，信用卡无此项
    data.setDeposits(new ArrayList());

    logger.info("平安银行开始抓取，taskKey:{}", context.get(LUA_TASK_KEY));

    //抓取基本信息
    crawlBaseInfo();

    //保存基本信息
    saveBasicInfo(data, cardNo);

    //抓取已出账单
    crawlDONEInfo();

    //保存已出账单
    saveDoneBills(data);

    //保存未出账单
    try {
        saveUndoneBills(data);
    } catch (e) {
        logger.error("平安银行解析未出账单异常, taskKey:{}"+context.get(LUA_TASK_KEY), e);
        statCaughtExceptionByJS(context, e);
    }
    return data;
}

function crawlBaseInfo() {
    //基本信息
    var baseInfoUrl = "https://creditcard.pingan.com.cn/financing/newccuser/resetShowIframefirstView.do?random0.4764434451437529";
    var baseInfo = luaFuncs.ajax_frame_get(baseInfoUrl, iframeName);
    storeDataToFile(context, baseInfo, num+"_card_1.txt");
    logger.info("平安银行基本信息，taskKey:{}", context.get(LUA_TASK_KEY));
    //获取有关账户的字段信息
    var fieldInfoUrl = "https://creditcard.pingan.com.cn/financing/newccuser/getSetAccountControllerRest.do";
    var fieldInfo = luaFuncs.ajax_frame_post(fieldInfoUrl, new HashMap(), iframeName);
    storeDataToFile(context, fieldInfo, num+"_card_2.txt")
    logger.info("平安银行获取基本字段，taskKey:{}", context.get(LUA_TASK_KEY));
    context.put("baseInfo",baseInfo);
    context.put("fieldInfo",fieldInfo);

}
/**
 * 未出账单bills
 */
function getUndoneBillAllData(data){
    //未出账单中，billAllDate无数据，只有shopping中有数据
    var billAllData = new BillAllData();
    billAllData.setBillType("UNDONE");
    billAllData.setBankName("平安银行");
    billAllData.setBillId(UUID.randomUUID().toString());

    var billTime = getBillTime("yyyy-MM");
    billAllData.setBillMonth(billTime);
    var billDateStr = commMap.get("billDate");
    var billDate = new StringBuilder();
    if(Integer.parseInt(billDateStr)<10){
        billDate.append(billTime).append("-").append("0").append(billDateStr);
    }else{
        billDate.append(billTime).append("-").append(billDateStr);
    }

    billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(billDate.toString()));
    setPaymentDueDate(billDateStr, billTime, billAllData);
    initNull(billAllData);

    billAllData.setCreditLimit(data.getCreditLimit());
    billAllData.setCashLimit(data.getCashLimit());
    billAllData.setInstallments(new ArrayList());
    //账单详情
    billAllData.setShoppingSheets(new ArrayList());
    billAllData.setNewCharges(undoneNewBalance);
    return billAllData;
}

/**
 * 设置未出账单还款日
 */
function setPaymentDueDate(billDateStr,billTime,billAllData){
    try {
        var billDateInt = Integer.parseInt(billDateStr);//账单日
        var payOffDate = commMap.get("payOffDate");
        if(StringUtils.isNotEmpty(payOffDate)){
            payOffDate = payOffDate.substring(payOffDate.length()-2, payOffDate.length());
            var payOffDateInt = Integer.parseInt(payOffDate);//还款日
            var paymentDueDate = new StringBuilder();
            var yearint = Integer.parseInt(billTime.substring(0, billTime.length()-3));
            if(payOffDateInt>billDateInt){
                paymentDueDate.append(billTime).append("-").append(payOffDateInt);
            }else{
                var newBillTime = Integer.parseInt(billTime.substring(billTime.length()-2, billTime.length()))+1;
                var billdate = "0"+newBillTime;
                var payoffDate = "0"+payOffDateInt;
                paymentDueDate.append(yearint).append("-").append(newBillTime<10?billdate:newBillTime).append("-").append(payOffDateInt<10?payoffDate:payOffDateInt);
                //paymentDueDate.append(newBillTime).append("-").append(payOffDateInt);
            }
            billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(paymentDueDate.toString()));
        }
    } catch (e) {
        billAllData.setPaymentDueDate(null);
        logger.error("set payment_due_date err.", e);
        statCaughtExceptionByJS(context, e);
    }
}

/**
 * 保存未出账单
 */
function crawlAndsaveUndoneBills(creditCardAllData){
    try {
        //获取未出账单信息
        var billAllData = getUndoneBillAllData(creditCardAllData);
        var expenseList = billAllData.getShoppingSheets();

        var orderIndex = 0;
        var currentPage = 0;
        var lastpayment = new BigDecimal("0.00");
        while(true){
            currentPage++;
            crawlUndoneBillInfo(currentPage,num);
            var undoneBill = context.get("undoneBill");
            var undoneBillMap = JSON.parse(undoneBill);
            //获取上期账单金额
            var payoffDetailDto = undoneBillMap.get("payoffDetailDto");
            var payment = undoneBillMap.get("SERVICE_RESPONSE_RESULT");
            var currentPayRecords = payoffDetailDto.get("currentPayRecords");
            var payoffDetailMap =  (payment.get("payoffDetail")).get(0);
            lastpayment = lastpayment.add(new BigDecimal(String.valueOf(payoffDetailMap.get("payBackMoney"))).negate());
            var size = currentPayRecords.size();
            if(size==0 || currentPage==100){
                break;
            }
            getShoppingExpenses(orderIndex,expenseList);
        }
        //上次账单金额
        billAllData.setLastPayment(lastpayment);
        //获取分期数据
        setShoppingInstallment(billAllData, expenseList);
        var bills = creditCardAllData.getBills();
        for(var i = bills.size();i<=bills.size();i++){
            //本期账单金额
            var new_balance = bills.get(bills.size()-1).getNewBalance().add(undoneNewBalance).add(lastpayment);
            var last_balance = bills.get(bills.size()-1).getNewBalance();//上期账单金额
            //本期账单金额
            billAllData.setNewBalance(new_balance);
            //上期账单金额
            billAllData.setLastBalance(last_balance);
            //本期新增款额
            billAllData.setNewCharges(undoneNewBalance);
        }
        creditCardAllData.getBills().add(billAllData);
    } catch (e) {
        logger.error("平安银行解析未出账单异常, taskKey:{}"+context.get(LUA_TASK_KEY), e);
        statCaughtExceptionByJS(context, e);
    }
}

function getShoppingExpenses(orderIndex,expenseList) {
    var undoneBill = context.get("undoneBill");
    var undoneBillMap = JSON.parse(undoneBill);
    //获取上期账单金额
    var payoffDetailDto = undoneBillMap.get("payoffDetailDto");
    var currentPayRecords = payoffDetailDto.get("currentPayRecords");
    for each(var payMap in currentPayRecords) {
        try {
            //获取消费信息
            expenseList.add(getShoppingExpense(payMap, false, ++orderIndex));
        } catch (e) {
            logger.error("平安银行解析消费信息异常, taskKey:{}"+context.get(LUA_TASK_KEY), e);
            statCaughtExceptionByJS(context, e);
        }
    }
}
function crawlUndoneBillInfo(currentPage,num) {
    var paramsMap = new HashMap();
    paramsMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
    paramsMap.put("accountNo", commMap.get("accountNo"));
    paramsMap.put("accountNoIndex", commMap.get("accountIndex"));
    paramsMap.put("acountType", commMap.get("acountType"));
    paramsMap.put("currentPage", currentPage);
    //获取未出账单
    var undoneBillUrl = generateURL("https://creditcard.pingan.com.cn/financing/newccuser/restPrintUnpaidBillPayoffDetail.do", paramsMap);
    var undoneBill = luaFuncs.ajax_frame_get(undoneBillUrl, iframeName);
    storeDataToFile(context, undoneBill, num+"_undonepage_"+currentPage+".txt");
    logger.info("平安银行未出账单，taskKey:{}", context.get(LUA_TASK_KEY));
    context.put("undoneBill",undoneBill);
}
/**
 * 保存已出账单
 */
function crawlAndSaveDoneBills(creditCardAllData){
    try {
        //前提条件
        beforeCrawlDone();
        //获取所有月份集合
        var monthList = getMonths();
        var dataList = creditCardAllData.getBills();
        var shopIndex = 0;//账单明细存储页面索引
        var installIndex = 0;//分期存储页面索引
        for (var i = 0; i < monthList.size(); i++) {
            var month = monthList.get(i);
            var orderIndex = 0;
            var billAllData = new BillAllData();
            //账单详情
            var expenseList = new ArrayList();
            var currentPage = 0;
            while(true){
                currentPage++;
                shopIndex++;
                //抓取已出账单信息
                crawlDoneInfo(month,currentPage,shopIndex,num);
                var detail = context.get("detail");
                var undoneBillMap = JSON.parse(detail);
                var payoffDetailDto = undoneBillMap.get("payoffDetailDto");
                var currentPayRecords = payoffDetailDto.get("currentPayRecords");
                var size = currentPayRecords.size();
                if(size==0 || currentPage==100){
                    break;
                }
                //保存已出账单信息
                setDoneBillAllData(billAllData, creditCardAllData);

                //获取消费明细数据
                getExpeseData(orderIndex,expenseList)

            }
            billAllData.setShoppingSheets(expenseList);
            //账单分期
            setShoppingInstallment(billAllData, expenseList);
            if(billAllData.getShoppingSheets().size()>0){
                dataList.add(billAllData);
            }
        }
    } catch (e) {
        logger.error("平安银行解析已出账单异常, taskKey:{}"+context.get(LUA_TASK_KEY), e);
        statCaughtExceptionByJS(context, e);
    }
}

function beforeCrawlDone() {
    var paramsMap = new HashMap();
    paramsMap.put("accountNo", commMap.get("accountNo"));
    paramsMap.put("accountSign", commMap.get("accountSign"));
    paramsMap.put("accountNoIndex", commMap.get("accountIndex"));
    paramsMap.put("acountType", commMap.get("acountType"));

    //获取已出账单信息
    var doneBillUrl = "https://creditcard.pingan.com.cn/financing/newccuser/querySummaryBill.do";
    var doneBill = luaFuncs.ajax_frame_post(doneBillUrl, new HashMap(), iframeName);
    storeDataToFile(context, doneBill, num+"_bills_1.txt")
    logger.info("平安银行已出账单，taskKey:{}", context.get(LUA_TASK_KEY));
}

function getExpeseData(orderIndex,expenseList) {
    var detail = context.get("detail");
    var undoneBillMap = JSON.parse(detail);
    var payoffDetailDto = undoneBillMap.get("payoffDetailDto");
    var currentPayRecords = payoffDetailDto.get("currentPayRecords");
    for each(var payMap in currentPayRecords) {
        try {
            //获取消费信息
            var expense = getShoppingExpense(payMap, true, ++orderIndex);
            expenseList.add(expense);
        } catch (e) {
            logger.error("平安银行解析消费信息异常, taskKey:{}",context.get(LUA_TASK_KEY));
            statCaughtExceptionByJS(context, e);
        }

    }
}
/**
 * 计算分期数据，从账单中筛选获得
 */
function setShoppingInstallment(billAllData,expenseList){
    if(expenseList==null || expenseList.size()<=0){
        return;
    }
    var freeList = new ArrayList();//手续费
    var periodList = new ArrayList();//期数
    for each(var expense in expenseList) {
        var des = expense.getDescription();
        if(des.contains("分期产品") && !des.contains("结清") && !des.contains("撤销") ){
            if(des.contains("手续费")){
                freeList.add(expense);
            }else{
                periodList.add(expense);
            }
        }else{
            if((des.contains("消费专用备用金")&&des.contains("期") )|| (des.contains("消费专用备用金") && des.contains("手续费"))){
                if(des.contains("手续费")){
                    freeList.add(expense);
                }else{
                    periodList.add(expense);
                }
            }
        }
    }

    var instList = new ArrayList();
    var countSize = freeList.size()>periodList.size()?periodList.size():freeList.size();
    for (var i = 0; i < countSize; i++) {
        var free = freeList.get(i);
        var period = periodList.get(i);
        var ins = new Installment();
        //分期描述
        ins.setInstallmentDesc(period.getDescription().replace(/\s+/g, ""));
        //手续费
        ins.setHandingfeeDesc(free.getDescription().replace(/\s+/g, ""));
        //账单编号
        ins.setBillId(UUID.randomUUID().toString());
        //交易时间
        ins.setTransDate(free==null ? null:free.getTransDate());
        //记账日
        ins.setPostDate(free==null ? null:free.getPostDate());
        //消费编号
        ins.setShoppingsheetId(UUID.randomUUID().toString());
        //分期类型
        ins.setInstallmentType("BILL");
        //分期手续费
        ins.setTransferFee(null);
        var list = new ArrayList();
        var r = Pattern.compile("\\d+");
        var m = r.matcher(period==null ? "":period.getDescription());
        while (m.find()) {
            list.add(Integer.parseInt(m.group()))
        }
        if(list.size()==2){
            ins.setTotalMonth(list.get(0));
            ins.setCurrentMonth(list.get(1));
        }
        //交易金额
        ins.setAmountMoney(period.getAmountMoney());
        //交易金额类型
        ins.setCurrencyType("CNY");
        //手续费
        ins.setHandingFee(free==null ? new BigDecimal("0"):free.getAmountMoney());
        instList.add(ins);
    }
    billAllData.setInstallments(instList);
}

/**
 * 格式化记账日期
 */
function getPostDate(settleDate){
    var now = Calendar.getInstance();
    var year = String.valueOf(now.get(Calendar.YEAR));

    var sb = new StringBuffer();
    sb.append(year).append("-");
    sb.append(settleDate.substring(0, 2)).append("-").append(settleDate.substring(2, 4));
    return sb.toString();
}

/**
 * 消费信息
 */
function getShoppingExpense(payMap, isdone, orderIndex){
    var txnDescTxt = payMap.get("txnDescTxt");//交易描述
    var expense = new Expense();
    //消费编号
    expense.setId(UUID.randomUUID().toString());
    //卡号
    expense.setCardNum(payMap.get("cardNo"));
    var settleDate = payMap.get("settleDate");
    //记账日
    expense.setPostDate(settleDate.contains("-") ? yyyy_MM_dd_PARSER.parse(settleDate) : yyyy_MM_dd_PARSER.parse(getPostDate( payMap.get("settleDate"))));//记账日期
    //判断消费类型
    expense.setCategory(judgeBillCategory(txnDescTxt));
    //编号
    expense.setOrderIndex(orderIndex);
    //币种
    expense.setCurrencyType(convertCurr(payMap, isdone));//币种

    var amountMoney = new BigDecimal(String.valueOf(payMap.get("txnAmount")));
    //如果交易金额为正相加
    if(!isdone && amountMoney.signum()>0){
        undoneNewBalance = undoneNewBalance.add(amountMoney);
    }

    expense.setAmountMoney(amountMoney);//消费金额
    expense.setBalance(null);
    expense.setTransAddr("");//交易地点
    //交易方式
    expense.setTransMethod("");
    //交易通道
    expense.setTransChannel("");
    //交易描述
    expense.setDescription(txnDescTxt==null ? "" : txnDescTxt.replace(/\s+/g, ""));
    //备注
    expense.setRemark("");
    //对方卡号
    expense.setOppositeCardNo("");
    //对方持卡人
    expense.setNameOnOppositeCard("");
    //对方银行
    expense.setOppositeBank("");
    //计算交易时间
    var txnDate =  payMap.get("txnDate");
    if(txnDate.length!=0 && txnDate.length()>=8){
        var sb = new StringBuilder(txnDate);//交易时间
        if(!txnDate.contains("-")){
            sb.insert(6, "-");
            sb.insert(4, "-");
        }
        sb.append(" 00:00:00");
        logger.info(sb)
        expense.setTransDate(yyyy_MM_dd_PARSER.parse(sb.toString()));
    }else{
        expense.setTransDate(null);
    }
    return expense;
}

/**
 * 根据中文币种生成英文币种
 */
function convertCurr(payMap,isdone) {
    if(isdone){//已出账单
        var currencyType = payMap.get("currencyType");
        if (StringUtils.isNotBlank(currencyType)) {
            if(currencyType.contains("C001")){
                return "CNY";
            }else{//美元方式暂时未知
                return "其他";
            }
        } else {
            return "";
        }
    }else{//未出账单
        var transCurrency = payMap.get("consumeCurType");
        if (StringUtils.isNotBlank(transCurrency)) {
            if (transCurrency.contains("RMB")) {
                return "CNY";
            }else {//美元方式暂时未知
                return "其他";
            }
        } else {
            return "";
        }
    }
}

/**
 * 根据描述判断账单的消费类型
 */
function judgeBillCategory(description) {
    if(StringUtils.isBlank(description)){
        return "";
    }
    if (description.contains("消费")) {
        return "SHOPPING";
    }else if (description.contains("取现")) {
        return "WITHDRAW";
    }else if (description.contains("还款")||description.contains("转入")) {
        return "PAYMENTS";
    }else if (description.contains("逾期利息")||description.contains("利息")) {
        return "INTEREST";
    }else if (description.contains("延滞金")) {
        return "OVERDUEPAYMENT";
    }else if (description.contains("超额费")) {
        return "OVERDUEFEE";
    }else if (description.contains("分期")) {
        return "INSTALLMENT";
    }else if (description.contains("年费")) {
        return "OTHERFEE";
    }else{
        return "SHOPPING";
    }
}

/**
 * 已出账单bills
 */
function setDoneBillAllData(billAllData,creditCardAllData){
    try {
        var detail = context.get("detail");
        var undoneBillMap = JSON.parse(detail);
        var resultMap = undoneBillMap.get("SERVICE_RESPONSE_RESULT");
        var payoffDetailMap = (resultMap.get("payoffDetail")).get(0);

        //账单类型
        billAllData.setBillType("DONE");
        //银行
        billAllData.setBankName("平安银行");
        //账单编号
        billAllData.setBillId(UUID.randomUUID().toString());
        //账单月份
        billAllData.setBillMonth((resultMap.get("billDate")).substring(0, 7));
        //账单日
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(resultMap.get("billDate")));

        var payOffDate = resultMap.get("payOffDate");
        commMap.put("payOffDate", payOffDate);
        //还款日
        billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(payOffDate));
        //本期账单金额
        billAllData.setNewBalance(new BigDecimal(String.valueOf(payoffDetailMap.get("amountToPayOff"))));
        //最低还款金额
        billAllData.setMinPayment(new BigDecimal(String.valueOf(payoffDetailMap.get("minAmountToPayOff"))));
        //上期账单金额
        billAllData.setLastBalance(new BigDecimal(String.valueOf(payoffDetailMap.get("preBillAmount"))));
        //上期还款金额
        billAllData.setLastPayment(new BigDecimal(String.valueOf(payoffDetailMap.get("preAmountPaidOff"))).negate());
        //本期新增款额
        billAllData.setNewCharges(new BigDecimal(String.valueOf(payoffDetailMap.get("billAmount"))));
        //循环利息
        billAllData.setInterest(new BigDecimal(String.valueOf(payoffDetailMap.get("accrualAmount"))));
        //信用卡额度
        billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
        //预借现金额度
        billAllData.setCashLimit(creditCardAllData.getCashLimit());
        billAllData.setInstallments(new ArrayList());
        //初始化null值
        initUsdNull(billAllData);
    } catch (e) {
        logger.error("平安银行解析已出账单bills异常, taskKey:{}"+context.get(LUA_TASK_KEY), e);
        statCaughtExceptionByJS(context, e);
    }
}

/**
 * 初始化null值
 */
function initNull(billAllData){
    billAllData.setMinPayment(null);
    billAllData.setInterest(null);
    initUsdNull(billAllData);
}

/**
 * 初始化null值，美元相关
 */
function initUsdNull(billAllData){
    //美元相关
    billAllData.setUsdCashLimit(null);
    billAllData.setUsdCreditLimit(null);
    billAllData.setUsdInterest(null);
    billAllData.setUsdLastBalance(null);
    billAllData.setUsdLastPayment(null);
    billAllData.setUsdMinPayment(null);
    billAllData.setUsdNewBalance(null);
    billAllData.setUsdNewCharges(null);
}

/**
 * 生成url连接参数格式：www.xxx.com?a=1&b=2
 */
function generateURL(inUrl,paramsMap) {
    var uri = null;
    try {
        var uriBuilder = new URIBuilder(inUrl);
        if (null != paramsMap) {
            for each(var entry in paramsMap.entrySet()) {
                uriBuilder.addParameter(entry.getKey(), entry.getValue());
            }
        }
        uri = uriBuilder.build();
        return uri.toString();
    } catch (e) {
        logger.error("pingan generateURL err.", e);
        statCaughtExceptionByJS(context, e);
    }
    return "";
}

/**
 * 获取月份
 */
function getMonths(){
    //发请求获取月份集合
    var url = "https://creditcard.pingan.com.cn/financing/newccuser/QueryPostedBillSum.do?0.34800668036505167";
    var rsp = luaFuncs.ajax_frame_get(url, iframeName);
    storeDataToFile(context, rsp,  num+"_months_1.txt")
    //判断网络是否异常
    if(StringUtils.isBlank(rsp) || rsp.contains("网络繁忙，请稍后再试")){
        throw new BankException(BACR_21301_10, "网络繁忙请稍后再试");
    }
    var rspMap = JSON.parse(rsp);
    var monthMap = rspMap.get("ACCOUNT_SUMMARY_BILL");
    var monthList =  monthMap.get("monthsOfBill");
    //将月份进行排序
    Collections.sort(monthList);
    return monthList;
}

function crawlDoneInfo(month,currentPage,shopIndex,num) {
    var paramsMap = new HashMap();
    paramsMap.put("accountNo", commMap.get("accountNo"));
    paramsMap.put("accountSign", commMap.get("accountSign"));
    paramsMap.put("accountNoIndex", commMap.get("accountIndex"));
    paramsMap.put("acountType", commMap.get("acountType"));
    paramsMap.put("queryMonth", month);
    paramsMap.put("defaultBillDate", month);
    paramsMap.put("currentPage", currentPage);
    //获取已出账单信息
    var doneBillDetailUrl = generateURL("https://creditcard.pingan.com.cn/financing/newccuser/printHistoryBillPayoffDetail.do?0.7439488723541526", paramsMap);
    var detail = luaFuncs.ajax_frame_get(doneBillDetailUrl, iframeName);
    storeDataToFile(context, detail, num+"_bill_shopping_sheets_"+shopIndex+".txt")
    logger.info("平安银行已出账单详情，taskKey:{}", context.get(LUA_TASK_KEY));
    context.put("detail",detail);

}
/**
 * 保存基本信息
 */
function saveBasicInfo(creditCardAllData){
    try {
        var cardNum = context.get("cardNo");
        var fieldInfo = context.get("fieldInfo");
        var baseInfo = context.get("baseInfo");
        var fieldMap = JSON.parse(fieldInfo);
        var customerMap = fieldMap.get("CUSTOMER");
        var detailMap = fieldMap.get("detail");
        commMap.put("accountNo", detailMap.get("accountNo"));
        commMap.put("accountIndex", String.valueOf(detailMap.get("accountIndex")));
        commMap.put("acountType", String.valueOf(detailMap.get("acountType")));
        commMap.put("accountSign", detailMap.get("accountSign"));
        var cardSet = detailMap.get("cardSet");
        //持卡人姓名
        creditCardAllData.setNameOnCard(customerMap.get("userName"));
        if(cardSet!=null && cardSet.size()>0){
            for (var i = 0; i < cardSet.size(); i++) {
                var cardMap = cardSet.get(i);
                var cardNo = cardMap.get("cardNo");
                if(cardNum.equals(cardNo)){
                    //卡号
                    creditCardAllData.setFullCardNum(cardNo);
                    //卡号后四位
                    creditCardAllData.setCardNum(cardNo.substring(cardNo.length()-4,cardNo.length()));
                }
            }
        }
        //卡的编号
        creditCardAllData.setCardId(UUID.randomUUID().toString());
        //卡类型
        creditCardAllData.setCardType("信用卡");
        //银行
        creditCardAllData.setBankName("平安银行");

        var baseInfoMap = JSON.parse(baseInfo);
        var resultMap = baseInfoMap.get("SERVICE_RESPONSE_RESULT");
        var billingCycle = baseInfoMap.get("billingCycle");
        //将账单日放到公共map中
        commMap.put("billDate", billingCycle);
        //可用信用额度
        creditCardAllData.setBalance(new BigDecimal(resultMap.get("availableLimit")));
        //信用额度
        creditCardAllData.setCreditLimit(new BigDecimal(resultMap.get("limit")));
        //现金额度
        creditCardAllData.setCashLimit(new BigDecimal(String.valueOf(resultMap.get("initialLimit"))).compareTo(new BigDecimal("0")) == 0?null:new BigDecimal(String.valueOf(resultMap.get("initialLimit"))));
        //可用取现额度
        creditCardAllData.setCashBalance(new BigDecimal(resultMap.get("cashLimit")));//信用卡现金可用额度
        //开户时间
        creditCardAllData.setOpenTime(yyyy_MM_dd_PARSER.parse(resultMap.get("dateOpen")));
    }catch(e){
        logger.error("平安银行解析基本信息异常, taskKey:{}"+context.get(LUA_TASK_KEY), e);
        statCaughtExceptionByJS(context, e);
    }

}

/**
 * 判断是否需要短信验证码
 * @throws InterruptedException
 */
function checkSms(){
    var url = "https://creditcard.pingan.com.cn/financing/newccuser/listAccountforCardInfo.do";
    var checkSms = null;
    var procount = 1;
    for(var count = 1;count<=3;count++){
        checkSms = luaFuncs.ajax_frame_post(url, new HashMap(), iframeName);
        storeDataToFile(context, checkSms, "check_issms.txt")
        if(checkSms.contains("您没有有效账户或您可能是附属卡用户")){
            return "您没有有效账户或您可能是附属卡用户";
        }else if(checkSms.contains("您目前没有已激活的卡片，或您的卡片状态异常，或卡片已过期")){
            return "您目前没有已激活的卡片，或您的卡片状态异常，或卡片已过期"
        }
        if(checkSms.contains("return is null")){
            luaFuncs.close_protocol();//如果有出现协议处理
            var propath = luaFuncs.get_screen_img();
            logger.info("关闭协议之后的页面地址是:{}",propath+count);
        }else{
            break;
        }
        Thread.sleep(2000);
        procount++;
    }
    if(procount>=3){
        logger.info("平安银行taskKey = {} 未获取到卡片信息",context.get(LUA_TASK_KEY));
        return "未获取到卡片信息，请登录官网绑定卡片";
    }
    //截图，返回保存当前页面的地址
    var imgpath = luaFuncs.get_screen_img();
    logger.info("当前页面的地址是{}",imgpath);
    var checkSmsMap = JSON.parse(checkSms);
    var retCode = checkSmsMap.get("ret_code");
    //078表示不需要短信验证码
    if("078".equals(retCode)){
        return "true";
    }
    return "false";
}

/**
 * 判断渲染页面加载状态
 */
function isExist(){
    var exist = luaFuncs.frame_is_exist_by_id("Tarrow01", "body");
    logger.info("平安银行页面渲染加载状态：{}, taskKey:{}", exist, context.get(LUA_TASK_KEY));
    return exist;
}

/**
 * 检查是否有信用卡信息
 */
function checkCard(loginHtml){
    //如果页面上包含添加信用卡五个字说明该用户没有信用卡卡片信息
    if(loginHtml.contains("添加信用卡")){
        checkCardTimes++;
    }
    if(checkCardTimes>1){
        return "没有相关信用卡卡片信息";
    }
    for (var i = 0; i < 3; i++) {
        //获取当前页面
        loginrsp = luaFuncs.find_frame_html();
        //如果页面为空或者页面内容为false，说明页面可能没有渲染完成，否则跳出循环
        if(StringUtils.isEmpty(loginrsp) || loginrsp.equals("false")){
            Thread.sleep(1000);
        }else{
            break;
        }
    }

    storeDataToFile(context, loginrsp, "1_homepage_1.txt")
    var doc = Jsoup.parse(loginrsp, "utf-8");
    var card = doc.select("#creditcard_PAUCreditCard_");
    //判断是否有信用卡信息
    if(card.size()==0 && loginrsp.contains("添加信用卡")){
        checkCardTimes++;
    }
    if(checkCardTimes>1){
        return "没有相关信用卡卡片信息";
    }
    return "true"
}

/**
 * 获取验证码
 */
function getCode(taskKey){
    imgCount++;
    //将获取的图片验证码地址存放在上下文中
    context.put(TASK_IMG_PATH, luaFuncs.get_frame_image_by_id());
    //图片验证码正则0-9的数字或者a-z的大小写，一共四位
    context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4}");
    //等待图片验证码60秒
    var code = waitImgCodeBySecondsByJs(context,60,true,3)
    logger.info("平安银行获取验证码，taskKey:{}, 验证码:{}", taskKey, code);
    //输入图片验证码
    var loginHtml = luaFuncs.set_frame_input_code(code);
    storeDataToFile(context, loginHtml, "1_login_"+imgCount+".txt")
    return loginHtml;
}

/**
 * 提取登录错误码
 * @param html
 * @returns {string}
 */
function getLoginErrorMsg(html){
    if(html.contains("信用卡-首页")){
        return "yes";
    }
    //对页面进行截取，只截取form部分，使用jsoup转换全部html会出转义字符无法解析
    var str = html.substring(html.indexOf("<form"),html.indexOf("<\/FORM>")+7)
    var errorMsg = "yes";
    var doc = Jsoup.parse(str);
    if(doc == null){
        return "未知错误"
    }
    var logon_form = doc.select("#logon_form");
    if(logon_form!=null){
        //提取错误内容 pa_ui_validator_onerror
        var error_div = logon_form.select(".pa_ui_validator_onerror")
        if(error_div!=null && error_div.size()>=1){
            errorMsg = error_div.get(0).text();
        }
    }
    return errorMsg;
}

var luaFuncs = {
    get: function (url) {
        var map = new HashMap();
        map.put("method","open");
        map.put("url",url);
        return sendAndReceive(map);
    },
    set_frame_input_text:function (text, pwd) {
        var map = new HashMap();
        map.put("method", "set_frame_input_text");
        map.put("username", text);
        map.put("password", pwd);
        return sendAndReceive(map);
    },
    get_frame_pwd:function () {
        var map = new HashMap();
        map.put("method", "get_frame_pwd");
        var msg = JSON.toJSONString(map);
        return sendAndReceive(map);
    },
    get_frame_image_by_id:function () {
        var map = new HashMap();
        map.put("method", "get_frame_image_by_id");
        return sendAndReceive(map);
    },
    set_frame_input_code:function (code) {
        var map = new HashMap();
        map.put("method", "set_frame_input_code");
        map.put("code", code);
        return sendAndReceive(map);
    },
    frame_is_exist_by_id:function (id, frames) {
        var map = new LinkedHashMap();
        map.put("method", "frame_is_exist_by_id");
        map.put("id", id);
        map.put("frame", frames);
        var result = sendAndReceive(map);
        if (StringUtils.isNotBlank(result) && result.equals("ok")) {
            return true;
        }
        return false;
    },
    get_screen_img:function () {
        var map = new HashMap();
        map.put("method", "get_screen_img");
        return sendAndReceive(map);
    },
    find_frame_html:function () {
        var map = new HashMap();
        map.put("method", "find_frame_html");
        return sendAndReceive(map);
    },
    check_is_id_exit:function () {
        var map = new HashMap();
        map.put("method", "check_is_id_exit");
        return sendAndReceive(map);
    },
    click_class_name_frame:function () {
        var map = new HashMap();
        map.put("method", "click_class_name_frame");
        return sendAndReceive(map);
    },
    click_credit:function () {
        var map = new HashMap();
        map.put("method", "click_credit");
        return sendAndReceive(map);
    },
    click_bill:function () {
        var map = new HashMap();
        map.put("method", "click_bill");
        return sendAndReceive(map);
    },
    ajax_frame_post:function (url, json, frames) {
        var map = new LinkedHashMap();
        map.put("method", "ajax_frame_post");
        map.put("url", url);
        map.put("json", json);
        map.put("frame", frames);
        return sendAndReceive(map);
    },
    close_protocol:function () {
        var map = new HashMap();
        map.put("method", "close_protocol");
        return sendAndReceive(map);
    },
    input_sms_frame:function (sms) {
        var map = new HashMap();
        map.put("method", "input_sms_frame");
        map.put("sms", sms);
        return sendAndReceive(map);
    },
    screen_print:function () {
        var map = new LinkedHashMap();
        map.put("method", "screen_print");
        return sendAndReceive(map);
    },
    ajax_frame_get:function (url,frames) {
        var map = new LinkedHashMap();
        map.put("method", "ajax_frame_get");
        map.put("url", url);
        map.put("frame", frames);
        return sendAndReceive(map);
    },
    check_code:function () {
        var map = new HashMap();
        map.put("method", "check_code");
        return sendAndReceive(map);
    },
    change_validate_img:function(){
        var map = new HashMap();
        map.put("method", "change_validate_img");
        return sendAndReceive(map);
    }
}